﻿namespace Webinator
{
    using Condition;
    using Enums;
    using Interfaces;

    /// <summary>
    /// Creates wait conditions.
    /// </summary>
    public static class WaitUntil
    {
        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">The desired collection size.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeEquals(Locator collection, int x)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.EqualTo, X = x };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">The desired collection size.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeEquals(Locator collection, int x, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.EqualTo, X = x, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must exceed X.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeGreaterThan(Locator collection, int x)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.GreaterThan, X = x };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must exceed X.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeGreaterThan(Locator collection, int x, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.GreaterThan, X = x, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must be less than X.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeLessThan(Locator collection, int x)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.LessThan, X = x };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must be less than X.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeLessThan(Locator collection, int x, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.LessThan, X = x, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must increase by X.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeIncreasedBy(Locator collection, int x)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.IncreasedBy, X = x };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must increase by X.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeIncreasedBy(Locator collection, int x, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.IncreasedBy, X = x, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must decrease by X.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeDecreasedBy(Locator collection, int x)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.DecreasedBy, X = x };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="collection">The collection.</param>
        /// <param name="x">Collection size must decrease by X.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition CollectionSizeDecreasedBy(Locator collection, int x, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new CollectionSize { Locator = collection, SizeIs = SizeIs.DecreasedBy, X = x, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="milliseconds">The time to wait in milliseconds.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition TimeElapsed(int milliseconds)
        {
            return new TimeElapsed { Milliseconds = milliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AjaxOrPostCompleted()
        {
            return new AjaxOrPostCompleted();
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AjaxOrPostCompleted(int timeoutInMilliseconds = 10000, bool throwException = true)
        {
            return new AjaxOrPostCompleted { ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NetworkTrafficSilent()
        {
            return new NetworkTrafficSilent();
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="gracePeriodInMilliseconds">Indicates how long of a period for which there should be no network activity.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NetworkTrafficSilent(int gracePeriodInMilliseconds)
        {
            return new NetworkTrafficSilent { GracePeriod = gracePeriodInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="gracePeriodInMilliseconds">Indicates how long of a period for which there should be no network activity.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NetworkTrafficSilent(int gracePeriodInMilliseconds, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NetworkTrafficSilent { GracePeriod = gracePeriodInMilliseconds, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition Displayed(Locator locator)
        {
            return new Displayed { Locator = locator };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition Displayed(Locator locator, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new Displayed { Locator = locator, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NotDisplayed(Locator locator)
        {
            return new NotDisplayed { Locator = locator };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NotDisplayed(Locator locator, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NotDisplayed { Locator = locator, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition Exists(Locator locator)
        {
            return new Exists { Locator = locator };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition Exists(Locator locator, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new Exists { Locator = locator, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NotExists(Locator locator)
        {
            return new NotExists { Locator = locator };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition NotExists(Locator locator, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NotExists { Locator = locator, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition UrlChanged()
        {
            return new UrlChanged { LookForText = null };
        }
        
        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="lookForText">The text to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition UrlChanged(string lookForText)
        {
            return new UrlChanged { LookForText = lookForText };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForText">The text to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition UrlChanged(Comparison comparison, string lookForText)
        {
            return new UrlChanged { LookForText = lookForText, Comparison = comparison };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForText">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition UrlChanged(Comparison comparison, string lookForText, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new UrlChanged { LookForText = lookForText, Comparison = comparison, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowTitleChanged()
        {
            return new WindowTitleChanged { LookForText = null };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="lookForText">The text to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowTitleChanged(string lookForText)
        {
            return new WindowTitleChanged { LookForText = lookForText };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForText">The text to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowTitleChanged(Comparison comparison, string lookForText)
        {
            return new WindowTitleChanged { LookForText = lookForText, Comparison = comparison };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForText">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowTitleChanged(Comparison comparison, string lookForText, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new WindowTitleChanged { LookForText = lookForText, Comparison = comparison, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <param name="attributeIs">The attribute.</param>
        /// <param name="lookForValue">
        /// The value to look for, if set to null then it looks for any change.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeChanged(Locator locator, AttributeIs attributeIs, string lookForValue)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, LookForValue = lookForValue, ChangeType = NodeChangeType.AttributeChanged };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attributeIs">The attribute.</param>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForValue">The value to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeChanged(Locator locator, AttributeIs attributeIs, Comparison comparison, string lookForValue)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, LookForValue = lookForValue, Comparison = comparison, ChangeType = NodeChangeType.AttributeChanged };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attributeIs">The attribute.</param>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForValue">The value to look for, if set to null then it looks for any change.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeChanged(Locator locator, AttributeIs attributeIs, Comparison comparison, string lookForValue, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, LookForValue = lookForValue, Comparison = comparison, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, ChangeType = NodeChangeType.AttributeChanged };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="lookForValue">
        /// The value to look for, if set to null then it looks for any change.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeChanged(Locator locator, string attribute, string lookForValue)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, LookForValue = lookForValue, ChangeType = NodeChangeType.AttributeChanged };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForValue">The value to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeChanged(Locator locator, string attribute, Comparison comparison, string lookForValue)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, LookForValue = lookForValue, Comparison = comparison, ChangeType = NodeChangeType.AttributeChanged };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForValue">The value to look for, if set to null then it looks for any change.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeChanged(Locator locator, string attribute, Comparison comparison, string lookForValue, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, LookForValue = lookForValue, Comparison = comparison, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, ChangeType = NodeChangeType.AttributeChanged };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <param name="attributeIs">The attribute.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeAdded(Locator locator, AttributeIs attributeIs)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, ChangeType = NodeChangeType.AttributeAdded };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attributeIs">The attribute.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeAdded(Locator locator, AttributeIs attributeIs, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, ChangeType = NodeChangeType.AttributeAdded };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <param name="attribute">The attribute.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeAdded(Locator locator, string attribute)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, ChangeType = NodeChangeType.AttributeAdded };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeAdded(Locator locator, string attribute, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, ChangeType = NodeChangeType.AttributeAdded };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <param name="attributeIs">The attribute.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeRemoved(Locator locator, AttributeIs attributeIs)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, ChangeType = NodeChangeType.AttributeRemoved };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attributeIs">The attribute.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeRemoved(Locator locator, AttributeIs attributeIs, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NodeChanged { Locator = locator, AttributeIs = attributeIs, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, ChangeType = NodeChangeType.AttributeRemoved };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">
        /// The locator.
        /// </param>
        /// <param name="attribute">The attribute.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeRemoved(Locator locator, string attribute)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, ChangeType = NodeChangeType.AttributeRemoved };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="locator">The locator.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition AttributeRemoved(Locator locator, string attribute, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new NodeChanged { Locator = locator, AttributeIs = AttributeIs.Custom, CustomAttribute = attribute, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, ChangeType = NodeChangeType.AttributeRemoved };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>value</c>.</param>
        /// <param name="value">The value to look for.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowAppearsUrl(Comparison comparison, string value)
        {
            return new WindowAppears { Comparison = comparison, SwitchBy = SwitchBy.Url, Value = value };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>value</c>.</param>
        /// <param name="value">The value to look for.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowAppearsUrl(Comparison comparison, string value, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new WindowAppears { Comparison = comparison, SwitchBy = SwitchBy.Url, Value = value, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>value</c>.</param>
        /// <param name="value">The value to look for.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowAppearsTitle(Comparison comparison, string value)
        {
            return new WindowAppears { Comparison = comparison, SwitchBy = SwitchBy.Title, Value = value };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>value</c>.</param>
        /// <param name="value">The value to look for.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowAppearsTitle(Comparison comparison, string value, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new WindowAppears { Comparison = comparison, SwitchBy = SwitchBy.Title, Value = value, TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowDisappears(int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new WindowDisappears { TimeoutInMilliseconds = timeoutInMilliseconds, ThrowException = throwException };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition WindowDisappears()
        {
            return new WindowDisappears();
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears()
        {
            return new DialogAppears();
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new DialogAppears { ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(string lookForTitle)
        {
            return new DialogAppears { LookForTitle = lookForTitle };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(string lookForTitle, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new DialogAppears { LookForTitle = lookForTitle, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(Comparison comparison, string lookForTitle)
        {
            return new DialogAppears { Comparison = comparison, LookForTitle = lookForTitle };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(Comparison comparison, string lookForTitle, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new DialogAppears { Comparison = comparison, LookForTitle = lookForTitle, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="parent">The <c>IWebManager</c> instance that is the parent of the dialog.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(IWebManager parent)
        {
            return new DialogAppears { Parent = parent.Process.MainWindowHandle };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="parent">The <c>IWebManager</c> instance that is the parent of the dialog.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(IWebManager parent, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new DialogAppears { Parent = parent.Process.MainWindowHandle, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="parent">The <c>IWebManager</c> instance that is the parent of the dialog.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(string lookForTitle, IWebManager parent)
        {
            return new DialogAppears { LookForTitle = lookForTitle, Parent = parent.Process.MainWindowHandle };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="parent">The <c>IWebManager</c> instance that is the parent of the dialog.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(string lookForTitle, IWebManager parent, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new DialogAppears { LookForTitle = lookForTitle, Parent = parent.Process.MainWindowHandle, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="parent">The <c>IWebManager</c> instance that is the parent of the dialog.</param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(Comparison comparison, string lookForTitle, IWebManager parent)
        {
            return new DialogAppears { Comparison = comparison, LookForTitle = lookForTitle, Parent = parent.Process.MainWindowHandle };
        }

        /// <summary>
        /// Creates an <c>ICondition</c> object.
        /// </summary>
        /// <param name="comparison">Indicates how to match the <c>LookForText</c>.</param>
        /// <param name="lookForTitle">The text to look for, if set to null then it looks for any change.</param>
        /// <param name="parent">The <c>IWebManager</c> instance that is the parent of the dialog.</param>
        /// <param name="timeoutInMilliseconds">The timeout in milliseconds.</param>
        /// <param name="throwException">
        /// A value indicating whether to throw an exception when the timeout has elapsed and the
        /// condition returns <c>false</c>.
        /// </param>
        /// <returns>
        /// An <c>ICondition</c> object.
        /// </returns>
        public static ICondition DialogAppears(Comparison comparison, string lookForTitle, IWebManager parent, int timeoutInMilliseconds = 5000, bool throwException = true)
        {
            return new DialogAppears { Comparison = comparison, LookForTitle = lookForTitle, ThrowException = throwException, TimeoutInMilliseconds = timeoutInMilliseconds, Parent = parent.Process.MainWindowHandle };
        }
    }
}
